package com.vincent.rpc.client.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vincent.rpc.common.bean.RpcRequest;
import com.vincent.rpc.common.bean.RpcResponse;
import com.vincent.rpc.common.registry.ServiceDiscovery;

/**
 * JDK 动态代理
 * @author vincent
 *
 */
public class JdkRpcProxy extends RpcProxy{

	private static final Logger LOGGER = LoggerFactory.getLogger(JdkRpcProxy.class);
	
	
	public JdkRpcProxy(String serviceAddress) {
        super(serviceAddress);
    }
	
	public JdkRpcProxy(ServiceDiscovery serviceDiscovery) {
		super(serviceDiscovery);
	}

	@Override
	public <T> T create(Class<?> interfaceClass) {
		return create(interfaceClass, "");
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T> T create(final Class<?> interfaceClass,final String serviceVersion) {
	     // 创建动态代理对象
        return (T) Proxy.newProxyInstance(
                interfaceClass.getClassLoader(),
                new Class<?>[]{interfaceClass},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        
                    	// 创建 RPC 请求对象并设置请求属性
                        RpcRequest request = makeupRequest(method, args, serviceVersion);
                        // 获取 RPC 服务地址
                        String serviceAddress = scanServiceAddress(interfaceClass, serviceVersion);
                        
                        RpcResponse response = sendRequest(serviceAddress, request);
                        if (response == null) {
                            throw new RuntimeException("response is null");
                        }
                        // 返回 RPC 响应结果
                        if (response.hasException()) {
                            throw response.getException();
                        } else {
                            return response.getResult();
                        }
                    }
                }
        );
	}
	
}
